CloudFrontのコンテンツの無圧縮、圧縮(BrotliとGzip)のリクエストを混在させた場合の挙動を確認してみた
いわさです。
CloudFrontにはコンテンツを圧縮して配信する機能が備わっています。
以下の記事ではBrotliの設定方法や圧縮されていることを確認しています。
CloudFront側では本日時点でGzipとBrotliの2つの圧縮形式がサポートされていますが、一方でブラウザ毎のコンテンツ圧縮形式のサポート状況は異なっています。
CDN側でそのあたりをどのように吸収しているのか、CloudFrontを使って挙動とキャッシュ動作を確認してみました。
※各ブラウザで何がサポートされているのかについてはこの記事では触れません。
圧縮設定
CloudFront側でコンテンツ圧縮を有効化するには2つの設定が必要です。
- キャッシュビヘイビアでの「オブジェクトを自動的に圧縮」を有効化します。
- キャッシュポリシーの圧縮サポートを有効化します。
デフォルトのキャッシュポリシーであればCachingOptimized
が圧縮サポートの有効化がされています。
圧縮サポートはGzip、Brotliそれぞれで有効化が可能です。
圧縮の確認
オリジン設定されたS3バケットに適当なHTMLファイルをコンテンツアップロードし確認してみます。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=1000, initial-scale=1.0"> <title>Document</title> </head> <body> ああああああああ ... ああああああ </body> </html>
CloudFrontでは、サイズが 1,000~10,000,000 バイトのオブジェクトを圧縮する仕様なので、その範囲内のファイルサイズであることを確認します。
また、圧縮するかどうかのファイルタイプもContent-Type
ヘッダーを使って判断されます。
クライアント毎にレスポンスを圧縮するか判断する仕組み
CloudFrontではリクエストのAccept-Encoding
にgzip
, br
, またはその両方が含まれていることによって圧縮を行います。
例えば、圧縮設定を有効にしたInternet Explorer 11だとgzip
のみ送信されbr
はサポートされていないので送信されません。
また、ChromeやFiregfoxを使った場合でもHTTPS利用時のみgzip,brを送付するなどブラウザによって対応状況や挙動は異なっています。
本日はcurlを使ってAccept-Encoding
ヘッダーを指定しレスポンスヘッダーを確認してみます。
無圧縮リクエスト
ここではContent-Encoding
を確認しレスポンスが圧縮されているかを判断します。
curlのデフォルトではAccept-Encoding
ヘッダーは付与されないので、圧縮されません。
iwasa.takahito@hoge 20211219cloudfront % curl -I http://d3ob3s1x9vrcur.cloudfront.net/hoge.html HTTP/1.1 200 OK Content-Type: text/html Content-Length: 105555 Connection: keep-alive Date: Sat, 18 Dec 2021 23:26:25 GMT Last-Modified: Sat, 18 Dec 2021 23:20:30 GMT ETag: "eac7a9e486d059b18d5d841a740c9aa8" Accept-Ranges: bytes Server: AmazonS3 Vary: Accept-Encoding X-Cache: Hit from cloudfront Via: 1.1 04c2f7c6be96060d3defd0bb02b9dbde.cloudfront.net (CloudFront) X-Amz-Cf-Pop: NRT12-C3 X-Amz-Cf-Id: Gwzpjl0cD6DsTEVFsCRZnVaqCuGXr0DoETIVhjc9Y1FGF61vusxjJg== Age: 585
Gzip
iwasa.takahito@hoge 20211219cloudfront % curl -H 'Accept-Encoding:gzip' -I http://d3ob3s1x9vrcur.cloudfront.net/hoge.html HTTP/1.1 200 OK Content-Type: text/html Server: AmazonS3 Content-Encoding: gzip Vary: Accept-Encoding
Brotli
iwasa.takahito@hoge 20211219cloudfront % curl -H 'Accept-Encoding:br' -I http://d3ob3s1x9vrcur.cloudfront.net/hoge.html HTTP/1.1 200 OK Content-Type: text/html Content-Encoding: br Vary: Accept-Encoding
GzipとBrotliが混在
多くのブラウザではGzipもBrotliもどちらもサポートされており、それをリクエスト時に伝えます。
その場合はAccept-Encoding
にサポート形式が全て格納されて伝わります。
両方サポートされている場合、CloudFrontではBrotliを優先します。
iwasa.takahito@hoge 20211219cloudfront % curl -H 'Accept-Encoding:br,gzip' -I http://d3ob3s1x9vrcur.cloudfront.net/hoge.html HTTP/1.1 200 OK Content-Type: text/html Content-Encoding: br Vary: Accept-Encoding iwasa.takahito@hoge 20211219cloudfront % curl -H 'Accept-Encoding:gzip,br' -I http://d3ob3s1x9vrcur.cloudfront.net/hoge.html HTTP/1.1 200 OK Content-Type: text/html Content-Encoding: br Vary: Accept-Encoding
なお、優先
なので、CloudFront側のキャッシュポリシーでBrotliがサポートされていない場合はGzipが次点で選択されます。
iwasa.takahito@hoge 20211219cloudfront % curl -H 'Accept-Encoding:gzip,br' -I http://d3ob3s1x9vrcur.cloudfront.net/hoge.html HTTP/1.1 200 OK Content-Type: text/html Content-Encoding: gzip Vary: Accept-Encoding
また、このキャッシュポリシー状態でクライアントがBrotliのみ要求する場合は無圧縮でレスポンスされます。
iwasa.takahito@hoge 20211219cloudfront % curl -H 'Accept-Encoding:br' -I http://d3ob3s1x9vrcur.cloudfront.net/hoge.html HTTP/1.1 200 OK Content-Type: text/html Vary: Accept-Encoding
キャッシュの確認
同一リクエストでもAccept-Encoding
に応じて複数の圧縮形式でレスポンスされることがわかりました。
もうひとつこの記事で確認しておきたいのが、圧縮形式ごとのキャッシュの取り扱いです。
圧縮形式のサポート状況が異なる複数のブラウザからアクセスされた場合にどのような挙動になるでしょうか。
この時点ではキャッシュキーに明示的にAccept-Encoding
は指定していません。
キャッシュを全て削除し、圧縮パターンごとに2回づつアクセスしたところ以下のような結果となりました。
iwasa.takahito@hoge 20211219cloudfront % curl -I http://d3ob3s1x9vrcur.cloudfront.net/hoge.html X-Cache: Miss from cloudfront iwasa.takahito@hoge 20211219cloudfront % curl -I http://d3ob3s1x9vrcur.cloudfront.net/hoge.html X-Cache: Hit from cloudfront iwasa.takahito@hoge 20211219cloudfront % curl -H 'Accept-Encoding:gzip' -I http://d3ob3s1x9vrcur.cloudfront.net/hoge.html Content-Encoding: gzip X-Cache: Miss from cloudfront iwasa.takahito@hoge 20211219cloudfront % curl -H 'Accept-Encoding:gzip' -I http://d3ob3s1x9vrcur.cloudfront.net/hoge.html Content-Encoding: gzip X-Cache: Hit from cloudfront iwasa.takahito@hoge 20211219cloudfront % curl -H 'Accept-Encoding:br' -I http://d3ob3s1x9vrcur.cloudfront.net/hoge.html Content-Encoding: br X-Cache: Miss from cloudfront iwasa.takahito@hoge 20211219cloudfront % curl -H 'Accept-Encoding:br' -I http://d3ob3s1x9vrcur.cloudfront.net/hoge.html Content-Encoding: br X-Cache: Hit from cloudfront
それぞれの1回目のアクセスでキャッシュされていますね。
当然だとは思いますが、異なる圧縮形式間でキャッシュを共有してしまうことはありませんでした。
CloudFrontはキャッシュキーに自動でAccept-Encoding
を含める仕様になっています。
逆に、明示的にキャッシュポリシーに指定した場合は圧縮しなくなってしまうようです。
念の為、異なるAccept-Encoding
が指定された場合にキャッシュがクリアされてしまわないことも確認しました。
iwasa.takahito@hoge 20211219cloudfront % curl -I http://d3ob3s1x9vrcur.cloudfront.net/hoge.html X-Cache: Hit from cloudfront iwasa.takahito@hoge 20211219cloudfront % curl -H 'Accept-Encoding:gzip' -I http://d3ob3s1x9vrcur.cloudfront.net/hoge.html Content-Encoding: gzip X-Cache: Hit from cloudfront iwasa.takahito@hoge 20211219cloudfront % curl -H 'Accept-Encoding:br' -I http://d3ob3s1x9vrcur.cloudfront.net/hoge.html Content-Encoding: br X-Cache: Hit from cloudfront
まとめ
本日は、Accept-Encoding
を指定した圧縮の確認と形式ごとのキャッシュの取り扱いについて確認してみました。
- CloudFrontは
Accept-Encoding
リクエストヘッダーに基づいてレスポンスの圧縮形式を判断している Accept-Encoding
を暗黙的にキャッシュキーに含まれてキャッシュされる
圧縮形式としてサポートされているのはgzipとbrですが、Accept-Encoding
の標準仕様にCloudFrontが則っていることを確認することが出来ました。いいですね。